<template>
  <div style="width: 100%;overflow-y:scroll;height: calc(100vh - 70px)">
    <div class="modern-forms" style="margin-top: 120px">
      <div class="modern-container">
        <form style="text-align: left">
          <fieldset>
            <div class="mdn-group">
              <label class="field-group mdn-upload">
                <input v-model="imgpath" type="text" class="mdn-input" placeholder="no file selected" @click="selectImg" readonly>
                <label class="mdn-label">File Load</label>
                <span class="mdn-bar"></span>
                <span class="mdn-button btn-primary"> Choose Image </span>
              </label>
            </div>
            <template v-if="imgpath">
              <div class="form-row">
                <div class="col col-6">
                  <div class="field-group mdn-select">
                    <select name="select" v-model="transformMethod">
                      <option value="negatives"> Image negatives</option>
                      <option value="log">Log Transformations</option>
                      <option value="gammar">Power-Law (Gammar) Transformations</option>
                      <option value="linear">Piecewise-Linear Transformations</option>
                    </select>
                    <label class="mdn-label">Select</label>
                    <span class="mdn-bar"></span>
                  </div>
                  <div class="mdn-group">
                    <label class="field-group mdn-upload">
                      <label class="mdn-label">Origin Image</label>
                      <img id="originImg"/>
                    </label>
                    <label class="field-group mdn-upload">
                      <label class="mdn-label">Intensity Image</label>
                      <canvas id="intensityImg"/>
                    </label>
                  </div>
                </div><!-- end col-4 -->
                <div class="col col-6">
                  <label class="field-group mdn-upload">
                    <label class="mdn-label">Transform Curves</label>
                    <div id="curves"></div>
                  </label>
                </div><!-- end col-8 -->
              </div><!-- end form-row -->
            </template>
          </fieldset>
        </form>
      </div><!-- modern-container -->
    </div><!-- modern-forms -->
  </div>
</template>

<script>
import * as d3 from "d3";

export default {
  name: "c3q2",
  data(){
    return{
      transformMethod:'negatives',
      imgpath:null
    }
  },
  watch:{
    transformMethod(val){
      if(this.imgpath) {
        this.drawImage()
        let container = document.getElementById('curves');
        container.removeChild(container.childNodes[0])
      }
    }
  },
  methods:{
    selectImg(){
      let input = document.createElement('input');
      input.type = 'file';
      return new Promise(function (resolve) {
        input.onchange = function(ev) {
          resolve(ev.target.files[0])
          return false;
        };
        input.click();
      }).then(file=>{
        this.imgpath = file.path
        return new Promise(function (resolve) {
          var reader = new FileReader();
          reader.onload = function(e){
            // target.result 该属性表示目标对象的DataURL
            let img = document.getElementById('originImg')
            // let img = document.createElement('img')
            // document.body.append(img)
            img.src = e.target.result
            img.onload = ()=>resolve()
          }
          // 传入一个参数对象即可得到基于该参数对象的文本内容
          reader.readAsDataURL(file);
        }).then(()=>{
          this.drawImage()
        })
      })
    },
    drawImage(){
      const method = (function (methodType){
        function limit(x){
          x = parseInt(x)
          x = Math.min(x,255)
          x = Math.max(x,0)
          return x
        }
        // 反色变换
        if (methodType === 'negatives') return (x,L = 256)=> limit(L - x - 1)
        // 对数变换
        if (methodType === 'log') return (x)=> limit(Math.log2(x+1) * 32)
        // gamma变换
        if (methodType === 'gammar') return (x,gammar = 2,L = 256)=> limit(Math.pow(x,gammar) / Math.pow(L,gammar - 1))
        // 分段线性
        if (methodType === 'linear') return (x,x1 = 100,y1 = 30,x2 = 156,y2 = 226, L = 256)=> {
          if(x <= x1) return limit(y1 * x / x1)
          else if(x > x2) return limit((L - 1 - y2) * (x - x2) / (L - 1 - x2) + y2)
          else return limit((y2 - y1) * (x - x1) / (x2 - x1) + y1)
        }
      })(this.transformMethod)
      const maper = d3.range(256).map(x=>method(x))
      const myTransformer = x=>maper[x]
      let img = document.getElementById('originImg')
      let canvas = document.getElementById('intensityImg')
      canvas.width = img.width;
      canvas.height = img.height;
      let ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0);
      let imageData = ctx.getImageData(0,0,img.width,img.height)
      for(let i = 0;i < imageData.data.length;i++){
        if(i%4 === 3) continue;
        imageData.data[i] = myTransformer(imageData.data[i])
      }
      ctx.clearRect(0,0,img.width,img.height);
      ctx.putImageData(imageData,0,0)
      this.drawCurves(myTransformer)
    },
    drawCurves(myTransformer) {
      const width = 250
      const height = 250
      const margin = {
        top: 10,
        bottom: 60,
        left: 30,
        right: 10
      }

      const svg = d3.select('#curves')
          .append('svg')
          .attr('width', width + margin.left + margin.right)
          .attr('height', height + margin.top + margin.bottom)
          .append('g')
          .attr('transform', `translate(${ margin.left }, ${ margin.top })`)

      const x = d3.scaleLinear()
          .domain([0, 256 ])
          .range([0, width])

      const y = d3.scaleLinear()
          .domain([0, 256])
          .range([height, 0])

      svg.append('g')
          .attr('transform', `translate(0, ${ height })`)
          .call(d3.axisBottom(x).ticks(15))

      svg.append('g')
          .call(d3.axisLeft(y).ticks(15))

      let line = d3.line()
          .x(function(d) { return x(d); })
          .y(function(d) { return y(myTransformer(d)); });

      svg.append('g')
          .append("path")
          .attr("d", line(d3.range(256)))
          .attr("stroke", "#2196f3")
          .attr("stroke-width", "2")
          .attr("fill", "none")
    }
  }
}
</script>

<style scoped>

</style>